<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .container h2{border-bottom: 1px gray solid;}
        .container .item{float: left;width: 100px;height: 40px;border: 1px blue solid;margin: 10px;}
    </style>
</head>
<body>
    <div class="container">
        <h2 class="page-header">点击切换颜色</h2>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>
</body>
<script>
    //获取div元素对象
    let items = document.getElementsByClassName("item");

    //遍历并绑定事件
    for(var i=0;i<items.length;i++){
        items[i].onclick = function(){
            this.style.background = 'pink';
            //items[i].style.background = 'pink'; 用let才行,是var的话是items[3]
        }
    } 

    /* const (虽然数组发生了变化，但是常量所指向的地址没有发生改变)*/
    const T = ['A','B','C'];
    T.push('RR');

    /*  let 不影响作用域链  */
    {
        let school = "xxx";
        function fn(){
            console.log(school); //xxx
        }
        fn();
    }

    /* 在非严格模式下，允许不用var声明变量，不用var声明的变量会默认为全局变量 所以b是全局变量，a是局部变量*/
    function fnc(){
        var a = b =30
        console.log(a,b) //30  30
    }
    fnc()
    console.log(b)  //30
    //console.log(a)  //is not defined

    /* 函数提升只会提升函数声明，而不会提升函数表达式
        函数提升要比变量提升的优先级要高一些，且不会被变量声明覆盖，但是会被变量赋值之后覆盖 */
    fn1() //fn1
    //fn2() //第一次fn2调用 变量提升 var fn2 此处没有函数提升 所以调用fn2()报错,因为fn2不是函数
    function fn1(){
        console.log('fn1')
    }
    var fn2 = function(){
        console.log('fn2')
    }
    fn2() //第二次fn2调用

    

    var foo = {n:1};
    (function(foo){            //形参foo同实参foo一样指向同一片内存空间，这个空间里的n的值为1
        var foo;               //优先级低于形参，无效。
        console.log(foo.n);    //输出1
        foo.n = 3;             //形参与实参foo指向的内存空间里的n的值被改为3
        foo = {n:2};           //形参foo指向了新的内存空间，里面n的值为2.
        console.log(foo.n);    //输出新的内存空间的n的值
    })(foo);
    console.log(foo.n);        //实参foo的指向还是原来的内存空间，里面的n的值为3.

    /* 异步编程 1s后输出111 2s后输出222 3s后输出333 */
    //旧方法 回调地狱 很宽代码
    /*
    setTimeout(()=>{
        console.log(111);
        setTimeout(()=>{
            console.log(222);
            setTimeout(()=>{
                console.log(333);
            },3000)
        },2000)
    },1000)
    */
   function one(){
       setTimeout(()=>{
        console.log(111);
        iterator.next()
    },1000)
   }
   function two(){
       setTimeout(()=>{
        console.log(222);
        iterator.next()
    },2000)
   }
   function three(){
       setTimeout(()=>{
        console.log(333);
        iterator.next()
    },3000)
   }
   function * gen(){
       yield one();
       yield two();
       yield three()
   }
   let iterator = gen();
    iterator.next()


   const p =new Promise(function(resolve,reject){
       setTimeout(function(){
           let data='数据库中的用户数据';
           //resolve(data);//对象的状态就会显示成功
           let err='失败了';
           reject(err);//对象的状态就会显示失败
       },1000)
   })
   //调用promise对象的then方法
   p.then(function(value){
       console.log(value);//调用成功的时候执行
   },function(reason){
       console.error(reason);//调用失败的时候执行
   })

   //then方法的返回结果是promise对象，对象状态由回调函数的执行结果决定
   //1.如果回调函数中的返回结果是 非 promise 类型的属性，状态为成功，返回值为对象的成功的值
   p.then(value=>{
       console.log(value);
   },reason=>{
       console.warn(reason);
   })

   p.catch(function(reason){
       console.warn(reason);
   })
</script>
</html>